﻿using System;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using QuickTest.Core.Compilation;
using QuickTest.Core.Events;
using QuickTest.Core.TestRunner;
using QuickTest.UI.Controls;

namespace QuickTest.Tests.UI.Controls
{
    [TestFixture]
    public class TestProgressBarTests
    {
        private TestProgressBar testProgressBar;
        private IEventHub eventHub;

        [SetUp]
        public void SetUp()
        {
            eventHub = new EventHub();
            testProgressBar = new TestProgressBar();
            testProgressBar.RegisterEvents(eventHub);
        }

        [Test]
        public void Can_Create_TestProgressBar()
        {
            Assert.That(testProgressBar, Is.InstanceOfType(typeof (ColorProgressBar)), "Should create an instance of ColorProgressBar base class");
            Assert.That(testProgressBar.Maximum, Is.EqualTo(100), "Should set initial maximum");
            Assert.That(testProgressBar.Value, Is.EqualTo(0), "Should set initial value");
            Assert.That(testProgressBar.ForeColor, Is.EqualTo(TestProgressBar.SuccessColor), "Should set initial colour");
        }

        [Test]
        public void Can_Set_Maximum()
        {
            eventHub.RaiseRunStarted(new TestRunStartedEventArgs(50));

            Assert.That(testProgressBar.Maximum, Is.EqualTo(50), "Should set maximum value");
        }

        [Test]
        public void Can_Update_Progress()
        {
            eventHub.RaiseRunStarted(new TestRunStartedEventArgs(10));

            eventHub.RaiseTestFinished(new TestEventArgs(new TestResult(String.Empty, ResultState.Success)));
            eventHub.RaiseTestFinished(new TestEventArgs(new TestResult(String.Empty, ResultState.Success)));

            Assert.That(testProgressBar.Value, Is.EqualTo(2), "Should update value");
            Assert.That(testProgressBar.StatusText, Is.EqualTo("Running test 2 of 10"), "Should update status text");
        }

        [Test]
        public void Can_Change_Colour_On_Failure()
        {
            eventHub.RaiseRunStarted(new TestRunStartedEventArgs(10));

            eventHub.RaiseTestFinished(new TestEventArgs(new TestResult(String.Empty, ResultState.Success)));
            Assert.That(testProgressBar.ForeColor, Is.EqualTo(TestProgressBar.SuccessColor), "Should initially be on success colour");

            eventHub.RaiseTestFinished(new TestEventArgs(new TestResult(String.Empty, ResultState.Failure)));
            Assert.That(testProgressBar.ForeColor, Is.EqualTo(TestProgressBar.FailureColor), "Should change to failure colour");

            eventHub.RaiseTestFinished(new TestEventArgs(new TestResult(String.Empty, ResultState.Success)));
            Assert.That(testProgressBar.ForeColor, Is.EqualTo(TestProgressBar.FailureColor), "Should remain of failure colour");
        }

        [Test]
        public void Can_Reset_Before_Each_Test_Run()
        {
            eventHub.RaiseRunStarted(new TestRunStartedEventArgs(10));

            eventHub.RaiseTestFinished(new TestEventArgs(new TestResult(String.Empty, ResultState.Success)));
            eventHub.RaiseTestFinished(new TestEventArgs(new TestResult(String.Empty, ResultState.Success)));

            eventHub.RaiseRunStarted(new TestRunStartedEventArgs(10));

            Assert.That(testProgressBar.Value, Is.EqualTo(0), "Should reset value");
            Assert.That(testProgressBar.Maximum, Is.EqualTo(10), "Should set maximum value");
            Assert.That(testProgressBar.StatusText, Is.EqualTo(String.Empty), "Should clear status text");
            Assert.That(testProgressBar.ForeColor, Is.EqualTo(TestProgressBar.SuccessColor), "Should reset progress bar colour");
        }

        [Test]
        public void Can_Show_Completed_Test_Run()
        {
            eventHub.RaiseRunFinished(new TestRunFinishedEventArgs(12, 5, 7, 0));

            Assert.That(testProgressBar.StatusText, Is.EqualTo("5 passed, 7 failed, 0 not executed"), "Should set completed status text");
        }

        [Test]
        public void Can_Handle_Zero_TestCount()
        {
            eventHub.RaiseRunStarted(new TestRunStartedEventArgs(0));

            Assert.That(testProgressBar.Maximum, Is.EqualTo(100), "Should not set maximum to 100");
        }

        [Test]
        public void should_reset_when_test_run_is_executed()
        {
            testProgressBar.Value = 50;

            eventHub.RaiseTestRunExecuted(EventArgs.Empty);

            Assert.That(testProgressBar.Value, Is.EqualTo(0));
        }

        [Test]
        public void should_show_a_failed_build()
        {
            eventHub.RaiseCompileFinished(new CompileFinishedEventArgs("Build failed", false));

            Assert.That(testProgressBar.ForeColor, Is.EqualTo(TestProgressBar.FailureColor));
        }
    }
}